package com.csproj.dispatch;

import com.csproj.basic.domain.Site;
import com.csproj.basic.repository.SiteRepository;
import com.csproj.dispatch.domain.Dispatch;
import com.csproj.dispatch.domain.Logistics;
import com.csproj.dispatch.domain.WarnInfo;
import com.csproj.dispatch.repository.DispatchRepository;
import com.csproj.dispatch.repository.LogisticsRepository;
import com.csproj.dispatch.repository.WarnInfoRepository;
import com.csproj.siiat.base.common.util.ReflectFactory;
import com.csproj.system.domain.UserInfo;
import com.csproj.system.repository.UserInfoRepository;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

public class BaseService<T> {
    @Resource(name = "siteRepository")
    private SiteRepository siteRepository;
    @Resource(name = "dispatchRepository")
    private DispatchRepository dispatchRepository;
    @Resource(name = "userInfoRepository")
    private UserInfoRepository userInfoRepository;
    @Resource(name = "logisticsRepository")
    private LogisticsRepository logisticsRepository;
    @Resource(name = "warnInfoRepository")
    private WarnInfoRepository warnInfoRepository;



    /**
     * 扩展launchsiteName
     * @return
     */
    public BaseService<T> extendLaunchsiteName(T dtoObject){
        String dtoObjectResourceParam = "launchsiteId";//dto对象的原本属性
        String dtoObjectResultParam = "launchsiteName";//dto对象的转换属性

        String launchsiteId = String.valueOf(getAttribute(dtoObject, dtoObjectResourceParam));
        Site site = siteRepository.findOne(launchsiteId);
        if(site != null){
            setAttribute(dtoObject, dtoObjectResultParam,site.getSiteName());
        }
        return this;
    }

    /**
     * 扩展destinationsiteName
     * @return
     */
    public BaseService<T> extendDestinationsiteName(T dtoObject){
        String dtoObjectResourceParam = "destinationsiteId";//dto对象的原本属性
        String dtoObjectResultParam = "destinationsiteName";//dto对象的转换属性

        String destinationsiteId = String.valueOf(getAttribute(dtoObject, dtoObjectResourceParam));
        Site site = siteRepository.findOne(destinationsiteId);
        if(site != null){
            setAttribute(dtoObject, dtoObjectResultParam,site.getSiteName());
        }
        return this;
    }

    /**
     * 扩展hasWarn
     * @return
     */
    public BaseService<T> extendHasWarn(T dtoObject){
        String dtoObjectResourceParam = "id";//dto对象的原本属性
        String dtoObjectResultParam = "hasWarn";//dto对象的转换属性


        String id = String.valueOf(getAttribute(dtoObject, dtoObjectResourceParam));
        List<WarnInfo> warnInfos = warnInfoRepository.findAllByDispatchIdOrderByCreationTime(id);

        if(warnInfos != null && !warnInfos.isEmpty()){
            setAttribute(dtoObject, dtoObjectResultParam,true);
        }else{
            setAttribute(dtoObject, dtoObjectResultParam,false);
        }
        return this;
    }



    /**
     * 扩展handleUserName
     * @return
     */
    public BaseService<T> extendHandleUserName(T dtoObject){
        String dtoObjectResourceParam = "handleUserId";//dto对象的原本属性
        String dtoObjectResultParam = "handleUserName";//dto对象的转换属性

        String handleUserId = String.valueOf(getAttribute(dtoObject, dtoObjectResourceParam));
        UserInfo userInfo = userInfoRepository.findOne(handleUserId);
        if(userInfo != null){
            setAttribute(dtoObject, dtoObjectResultParam,userInfo.getAccount());
        }
        return this;
    }

    /**
     * 调度信息获取
     * 电子锁编号、集装箱编号、路径编号、启运站点名称、目的站点名称
     * @param dtoObject
     * @return
     */
    public BaseService<T> extendDispatchInfo(T dtoObject){
        String dispatchId = String.valueOf(getAttribute(dtoObject, "dispatchId"));
        if(!StringUtils.isEmpty(dispatchId)){
            Dispatch dispatch = dispatchRepository.findOne(dispatchId);
            if(dispatch != null){
                // 电子锁编号
                setAttribute(dtoObject, "lockCode", dispatch.getLockCode());
                // 车牌号
                //获取物流信息
                if(!StringUtils.isEmpty(dispatch.getContainerId())){
                    Logistics logistics = logisticsRepository.
                            findFirstByContainerIdAndDeletionTimeIsNullOrderByCreationTimeDesc(dispatch.getContainerId());
                    if(logistics != null){
                        setAttribute(dtoObject, "transportCode", logistics.getTransportCode());
                    }
                }
                //集装箱编号
                setAttribute(dtoObject, "containerCode", dispatch.getContainerCode());
                //路径编号
                setAttribute(dtoObject, "routeCode", dispatch.getRouteCode());
                if(!StringUtils.isEmpty(dispatch.getLaunchsiteId())){
                    //启运站点名
                    Site site = siteRepository.findOne(dispatch.getLaunchsiteId());
                    if(site != null) {
                        setAttribute(dtoObject, "launchsiteName", site.getSiteName());
                    }
                }
                if(!StringUtils.isEmpty(dispatch.getDestinationsiteId())) {
                    //目的站点名
                    Site site1 = siteRepository.findOne(dispatch.getDestinationsiteId());
                    if (site1 != null) {
                        setAttribute(dtoObject, "destinationsiteName", site1.getSiteName());
                    }
                }
            }
        }

        return this;
    }


    /**
     * 获取方法属性
     * @param dtoObject
     * @param attribute
     * @return
     */
    private String getAttribute(T dtoObject, String attribute) {
        String getMethodName = "get" + attribute.substring(0, 1).toUpperCase() + attribute.substring(1); // 将属性的首字符大写，方便构造get，set方法
        Object value = new ReflectFactory<T>()
                .setObject(dtoObject)
                .setMethodName(getMethodName)
                .invoke();
        if(value != null){
            return value.toString();
        }
        return null;
    }


    /**
     * 设置方法属性
     * @param object
     * @param attribute
     * @param value
     */
    private void setAttribute(T object, String attribute, Object value) {
        if(value == null){
            return;
        }
        String getMethodName = "get" + attribute.substring(0, 1).toUpperCase() + attribute.substring(1); // 将属性的首字符大写，方便构造get，set方法
        Object attributeValue = new ReflectFactory<T>()
                .setObject(object)
                .setMethodName(getMethodName)
                .invoke();
        if(attributeValue == null){
            String setMethodName = "set" + attribute.substring(0, 1).toUpperCase() + attribute.substring(1); // 将属性的首字符大写，方便构造get，set方法
            new ReflectFactory<T>()
                    .setObject(object)
                    .setMethodName(setMethodName)
                    .setParameterTypes(value.getClass())
                    .setParameter(value)
                    .invoke();
        }
    }
}
